﻿using CTP.CRM.Core.Common.Dto;
using System.Security.Cryptography;
using System.Text;
using Volo.Abp.DependencyInjection;
using XC.RSAUtil;

namespace CTP.CRM.Core.Provider
{
    /// <summary>
    /// 非对称加密
    /// </summary>
    public class AsymmetricEncryptionProvider : IAsymmetricEncryptionProvider, IScopedDependency
    {
        private readonly IConfiguration _configuration = null;
        private const string STRCONTENTISNULL = "字符串内容为空.";
        private const string STRCONTENTISEXCEPTION = "字符串格式异常.";

        public AsymmetricEncryptionProvider(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="ciphertext"></param>
        /// <returns></returns>
        public BasicResponseDto DeEncryption(string ciphertext)
        {
            //var XMLConfiguration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory).AddXmlFile(path: "config.xml").Build();
            //var configList = XMLConfiguration.AsEnumerable();

            string privateKey = _configuration.GetSection("PrivateKey").Value;//;.First(m => m.Key == "PrivateKey").Value;
            string publicKey = _configuration.GetSection("PublicKey").Value; //configList.First(m => m.Key == "PublicKey").Value;

            var res = new BasicResponseDto();

            try
            {
                var decrypt = new RsaPkcs1Util(Encoding.UTF8, publicKey, privateKey); //创建解密对象
                var encryptionResult = decrypt.Decrypt(ciphertext, RSAEncryptionPadding.Pkcs1);//解密
                res.Data = encryptionResult;
                res.Success = true;
            }
            catch (Exception ex)
            {
                //显示解密失败原因
                var reson = "";
                if (string.IsNullOrEmpty(ciphertext))
                {
                    reson = STRCONTENTISNULL;
                }
                else if (ex is FormatException) // 字符串不是标准的 base64 字符串
                {
                    reson = $"{STRCONTENTISEXCEPTION}{ex.Message}";
                }
                res.Success = false;
                res.ErrorMessage = reson;
            }
            return res;
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="Content"></param>
        /// <returns></returns>
        public BasicResponseDto Encryption(string Content)
        {
            //var xmlConfiguration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory).AddXmlFile(path: "config.xml").Build();
            //var configList = xmlConfiguration.AsEnumerable();
            //string publicKey = configList.First(m => m.Key == "PublicKey").Value;
            string publicKey = _configuration.GetSection("PublicKey").Value;
            string resStr = new RsaPkcs1Util(Encoding.UTF8, publicKey).Encrypt(Content, RSAEncryptionPadding.Pkcs1);
            var res = new BasicResponseDto
            {
                Data = resStr
            };
            return res;
        }

        /// <summary>
        /// 获取新的公钥私钥
        /// </summary>
        /// <returns></returns>
        public BasicResponseDto GetNewKeys()
        {
            var keyList = RsaKeyGenerator.Pkcs1Key(2048, true);
            var privateKey = keyList[0];
            var publicKey = keyList[1];
            var res = new BasicResponseDto();
            res.Data = new { PublicKey = publicKey, PrivateKey = privateKey };
            return res;
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="Content"></param>
        /// <param name="uppercase"></param>
        /// <returns></returns>
        public BasicResponseDto MD5Encryption(string Content, bool uppercase = false)
        {
            using MD5 mD = MD5.Create();
            byte[] array = mD.ComputeHash(Encoding.UTF8.GetBytes(Content));
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < array.Length; i++)
            {
                stringBuilder.Append(array[i].ToString("x2"));
            }

            string text2 = stringBuilder.ToString();
            var res = new BasicResponseDto();
            res.Data = (!uppercase) ? text2 : text2.ToUpper();
            return res;
        }
    }
}
